/**

 @Name：transfer 穿梭框组件
 @License：MIT

 */
import $ from 'jquery';
import laytpl from "./laytpl";
import form from "./form";
import layui from "./layui";

var MOD_NAME = 'transfer'

	//外部接口
	, transfer = {
		config: {}
		, index: 0

		//设置全局项
		, set: function (options) {
			var that = this;
			that.config = $.extend({}, that.config, options);
			return that;
		}

		//事件
		, on: function (events, callback) {
			return layui.onevent.call(this, MOD_NAME, events, callback);
		}
	}

	//操作当前实例
	, thisModule = function () {
		var that = this
			, options = that.config
			, id = options.id || that.index;

		thisModule.that[id] = that; //记录当前实例对象
		thisModule.config[id] = options; //记录当前实例配置项

		return {
			config: options
			//重置实例
			, reload: function (options) {
				that.reload.call(that, options);
			}
			//获取右侧数据
			, getData: function () {
				return that.getData.call(that);
			}
		}
	}

	//获取当前实例配置项
	, getThisModuleConfig = function (id) {
		var config = thisModule.config[id];
		if (!config) hint.error('The ID option was not found in the ' + MOD_NAME + ' instance');
		return config || null;
	}

	//字符常量
	, ELEM = 'layui-transfer', HIDE = 'layui-hide', DISABLED = 'layui-btn-disabled', NONE = 'layui-none'
	, ELEM_BOX = 'layui-transfer-box', ELEM_HEADER = 'layui-transfer-header', ELEM_SEARCH = 'layui-transfer-search',
	ELEM_ACTIVE = 'layui-transfer-active', ELEM_DATA = 'layui-transfer-data'

	//穿梭框模板
	, TPL_BOX = function (obj) {
		obj = obj || {};
		return ['<div class="layui-transfer-box" data-index="' + obj.index + '">'
			, '<div class="layui-transfer-header">'
			, '<input type="checkbox" name="' + obj.checkAllName + '" lay-filter="layTransferCheckbox" lay-type="all" lay-skin="primary" title="{{ d.data.title[' + obj.index + '] || \'list' + (obj.index + 1) + '\' }}">'
			, '</div>'
			, '{{# if(d.data.showSearch){ }}'
			, '<div class="layui-transfer-search">'
			, '<i class="layui-icon layui-icon-search"></i>'
			, '<input type="input" class="layui-input" placeholder="关键词搜索">'
			, '</div>'
			, '{{# } }}'
			, '<ul class="layui-transfer-data"></ul>'
			, '</div>'].join('');
	}

	//主模板
	, TPL_MAIN = ['<div class="layui-transfer layui-form layui-border-box" lay-filter="LAY-transfer-{{ d.index }}">'
		, TPL_BOX({
			index: 0
			, checkAllName: 'layTransferLeftCheckAll'
		})
		, '<div class="layui-transfer-active">'
		, '<button type="button" class="layui-btn layui-btn-sm layui-btn-primary layui-btn-disabled" data-index="0">'
		, '<i class="layui-icon layui-icon-next"></i>'
		, '</button>'
		, '<button type="button" class="layui-btn layui-btn-sm layui-btn-primary layui-btn-disabled" data-index="1">'
		, '<i class="layui-icon layui-icon-prev"></i>'
		, '</button>'
		, '</div>'
		, TPL_BOX({
			index: 1
			, checkAllName: 'layTransferRightCheckAll'
		})
		, '</div>'].join('')

	//构造器
	, Class = function (options) {
		var that = this;
		that.index = ++transfer.index;
		that.config = $.extend({}, that.config, transfer.config, options);
		that.render();
	};

//默认配置
Class.prototype.config = {
	title: ['列表一', '列表二']
	, width: 200
	, height: 360
	, data: [] //数据源
	, value: [] //选中的数据
	, showSearch: false //是否开启搜索
	, id: '' //唯一索引，默认自增 index
	, text: {
		none: '无数据'
		, searchNone: '无匹配数据'
	}
};

//重载实例
Class.prototype.reload = function (options) {
	var that = this;
	that.config = $.extend({}, that.config, options);
	that.render();
};

//渲染
Class.prototype.render = function () {
	var that = this
		, options = that.config;

	//解析模板
	var thisElem = that.elem = $(laytpl(TPL_MAIN).render({
		data: options
		, index: that.index //索引
	}));

	var othis = options.elem = $(options.elem);
	if (!othis[0]) return;

	//初始化属性
	options.data = options.data || [];
	options.value = options.value || [];

	//索引
	that.key = options.id || that.index;

	//插入组件结构
	othis.html(that.elem);

	//各级容器
	that.layBox = that.elem.find('.' + ELEM_BOX)
	that.layHeader = that.elem.find('.' + ELEM_HEADER)
	that.laySearch = that.elem.find('.' + ELEM_SEARCH)
	that.layData = thisElem.find('.' + ELEM_DATA);
	that.layBtn = thisElem.find('.' + ELEM_ACTIVE + ' .layui-btn');

	//初始化尺寸
	that.layBox.css({
		width: options.width
		, height: options.height
	});
	that.layData.css({
		height: function () {
			return options.height - that.layHeader.outerHeight() - that.laySearch.outerHeight() - 2
		}()
	});

	that.renderData(); //渲染数据
	that.events(); //事件
};

//渲染数据
Class.prototype.renderData = function () {
	var that = this
		, options = that.config;

	//左右穿梭框差异数据
	var arr = [{
		checkName: 'layTransferLeftCheck'
		, views: []
	}, {
		checkName: 'layTransferRightCheck'
		, views: []
	}];

	//解析格式
	that.parseData(function (item) {
		//标注为 selected 的为右边的数据
		var _index = item.selected ? 1 : 0
			, listElem = ['<li>'
			, '<input type="checkbox" name="' + arr[_index].checkName + '" lay-skin="primary" lay-filter="layTransferCheckbox" title="' + item.title + '"' + (item.disabled ? ' disabled' : '') + (item.checked ? ' checked' : '') + ' value="' + item.value + '">'
			, '</li>'].join('');
		arr[_index].views.push(listElem);
		delete item.selected;
	});

	that.layData.eq(0).html(arr[0].views.join(''));
	that.layData.eq(1).html(arr[1].views.join(''));

	that.renderCheckBtn();
}

//渲染表单
Class.prototype.renderForm = function (type) {
	form.render(type, 'LAY-transfer-' + this.index);
};

//同步复选框和按钮状态
Class.prototype.renderCheckBtn = function (obj) {
	var that = this
		, options = that.config;

	obj = obj || {};

	that.layBox.each(function (_index) {
		var othis = $(this)
			, thisDataElem = othis.find('.' + ELEM_DATA)
			, allElemCheckbox = othis.find('.' + ELEM_HEADER).find('input[type="checkbox"]')
			, listElemCheckbox = thisDataElem.find('input[type="checkbox"]');

		//同步复选框和按钮状态
		var nums = 0
			, haveChecked = false;
		listElemCheckbox.each(function () {
			var isHide = $(this).data('hide');
			if (this.checked || this.disabled || isHide) {
				nums++;
			}
			if (this.checked && !isHide) {
				haveChecked = true;
			}
		});

		allElemCheckbox.prop('checked', haveChecked && nums === listElemCheckbox.length); //全选复选框状态
		that.layBtn.eq(_index)[haveChecked ? 'removeClass' : 'addClass'](DISABLED); //对应的按钮状态

		//无数据视图
		if (!obj.stopNone) {
			var isNone = thisDataElem.children('li:not(.' + HIDE + ')').length
			that.noneView(thisDataElem, isNone ? '' : options.text.none);
		}
	});

	that.renderForm('checkbox');
};

//无数据视图
Class.prototype.noneView = function (thisDataElem, text) {
	var createNoneElem = $('<p class="layui-none">' + (text || '') + '</p>');
	if (thisDataElem.find('.' + NONE)[0]) {
		thisDataElem.find('.' + NONE).remove();
	}
	text.replace(/\s/g, '') && thisDataElem.append(createNoneElem);
};

//同步 value 属性值
Class.prototype.setValue = function () {
	var that = this
		, options = that.config
		, arr = [];
	that.layBox.eq(1).find('.' + ELEM_DATA + ' input[type="checkbox"]').each(function () {
		var isHide = $(this).data('hide');
		isHide || arr.push(this.value);
	});
	options.value = arr;

	return that;
};

//解析数据
Class.prototype.parseData = function (callback) {
	var that = this
		, options = that.config
		, newData = [];

	layui.each(options.data, function (index, item) {
		//解析格式
		item = (typeof options.parseData === 'function'
			? options.parseData(item)
			: item) || item;

		newData.push(item = $.extend({}, item))

		layui.each(options.value, function (index2, item2) {
			if (item2 == item.value) {
				item.selected = true;
			}
		});
		callback && callback(item);
	});

	options.data = newData;
	return that;
};

//获得右侧面板数据
Class.prototype.getData = function (value) {
	var that = this
		, options = that.config
		, selectedData = [];

	that.setValue();

	layui.each(value || options.value, function (index, item) {
		layui.each(options.data, function (index2, item2) {
			delete item2.selected;
			if (item == item2.value) {
				selectedData.push(item2);
			}
			;
		});
	});
	return selectedData;
};

//事件
Class.prototype.events = function () {
	var that = this
		, options = that.config;

	//左右复选框
	that.elem.on('click', 'input[lay-filter="layTransferCheckbox"]+', function () {
		var thisElemCheckbox = $(this).prev()
			, checked = thisElemCheckbox[0].checked
			, thisDataElem = thisElemCheckbox.parents('.' + ELEM_BOX).eq(0).find('.' + ELEM_DATA);

		if (thisElemCheckbox[0].disabled) return;

		//判断是否全选
		if (thisElemCheckbox.attr('lay-type') === 'all') {
			thisDataElem.find('input[type="checkbox"]').each(function () {
				if (this.disabled) return;
				this.checked = checked;
			});
		}

		that.renderCheckBtn({stopNone: true});
	});

	//按钮事件
	that.layBtn.on('click', function () {
		var othis = $(this)
			, _index = othis.data('index')
			, thisBoxElem = that.layBox.eq(_index)
			, arr = [];
		if (othis.hasClass(DISABLED)) return;

		that.layBox.eq(_index).each(function (_index) {
			var othis = $(this)
				, thisDataElem = othis.find('.' + ELEM_DATA);

			thisDataElem.children('li').each(function () {
				var thisList = $(this)
					, thisElemCheckbox = thisList.find('input[type="checkbox"]')
					, isHide = thisElemCheckbox.data('hide');

				if (thisElemCheckbox[0].checked && !isHide) {
					thisElemCheckbox[0].checked = false;
					thisBoxElem.siblings('.' + ELEM_BOX).find('.' + ELEM_DATA).append(thisList.clone());
					thisList.remove();

					//记录当前穿梭的数据
					arr.push(thisElemCheckbox[0].value);
				}

				that.setValue();
			});
		});

		that.renderCheckBtn();

		//穿梭时，如果另外一个框正在搜索，则触发匹配
		var siblingInput = thisBoxElem.siblings('.' + ELEM_BOX).find('.' + ELEM_SEARCH + ' input')
		siblingInput.val() === '' || siblingInput.trigger('keyup');

		//穿梭时的回调
		options.onchange && options.onchange(that.getData(arr), _index);
	});

	//搜索
	that.laySearch.find('input').on('keyup', function () {
		var value = this.value
			, thisDataElem = $(this).parents('.' + ELEM_SEARCH).eq(0).siblings('.' + ELEM_DATA)
			, thisListElem = thisDataElem.children('li');

		thisListElem.each(function () {
			var thisList = $(this)
				, thisElemCheckbox = thisList.find('input[type="checkbox"]')
				, isMatch = thisElemCheckbox[0].title.indexOf(value) !== -1;

			thisList[isMatch ? 'removeClass' : 'addClass'](HIDE);
			thisElemCheckbox.data('hide', isMatch ? false : true);
		});

		that.renderCheckBtn();

		//无匹配数据视图
		var isNone = thisListElem.length === thisDataElem.children('li.' + HIDE).length;
		that.noneView(thisDataElem, isNone ? options.text.searchNone : '');
	});
};

//记录所有实例
thisModule.that = {}; //记录所有实例对象
thisModule.config = {}; //记录所有实例配置项

//重载实例
transfer.reload = function (id, options) {
	var that = thisModule.that[id];
	that.reload(options);

	return thisModule.call(that);
};

//获得选中的数据（右侧面板）
transfer.getData = function (id) {
	var that = thisModule.that[id];
	return that.getData();
};

//核心入口
transfer.render = function (options) {
	var inst = new Class(options);
	return thisModule.call(inst);
};

export default transfer;
